package com.vlyman.shiro.service.impl;

import com.vlyman.builder.QueryWrapperBuilder;
import com.vlyman.shiro.entity.SysPermissionFilter;
import com.vlyman.shiro.service.ShiroService;
import com.vlyman.shiro.service.SysPermissionFilterService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.util.CollectionUtils;
import org.apache.shiro.web.filter.mgt.DefaultFilterChainManager;
import org.apache.shiro.web.filter.mgt.PathMatchingFilterChainResolver;
import org.apache.shiro.web.servlet.AbstractShiroFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * 类描述：
 *
 * @author chenjs
 * @date 2018/12/29 23:17
 **/
@Slf4j
@Service
public class ShiroServiceImpl implements ShiroService {

    @Autowired
    private ShiroFilterFactoryBean shiroFilterFactoryBean;
    @Autowired
    private SysPermissionFilterService sysPermissionFilterServiceImpl;

    /**
     * 方法描述：
     * 初始化权限
     *
     * @return Map<String, String> shiro拦截器map
     * @author chenjs
     * @date 2018/12/29 23:15
     */
    @Override
    public Map<String, String> loadFilterChainDefinitions() {
        // 权限控制map.从数据库获取
        Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
        List<SysPermissionFilter> filterList = sysPermissionFilterServiceImpl.list(
            QueryWrapperBuilder.init(SysPermissionFilter.class)
                .orderByAsc(SysPermissionFilter.SORT)
        );
        filterList.forEach(item -> filterChainDefinitionMap.put(
            item.getUri(), item.getPermission()
        ));
        return filterChainDefinitionMap;
    }

    /**
     * 方法描述：
     *   重新加载权限
     *  @author chenjs
     *  @date 2018/12/29 23:17
     */
    @Override
    public void reloadPermisson() {
        //强制同步，控制线程安全
        synchronized (shiroFilterFactoryBean) {
            AbstractShiroFilter shiroFilter = null;
            try {
                shiroFilter = (AbstractShiroFilter) shiroFilterFactoryBean.getObject();
                PathMatchingFilterChainResolver filterChainResolver = (PathMatchingFilterChainResolver) shiroFilter
                        .getFilterChainResolver();
                // 过滤管理器
                DefaultFilterChainManager manager = (DefaultFilterChainManager) filterChainResolver
                        .getFilterChainManager();
                // 清空旧的权限控制
                manager.getFilterChains().clear();
                shiroFilterFactoryBean.getFilterChainDefinitionMap().clear();
                // 重新设置权限
                shiroFilterFactoryBean.setFilterChainDefinitionMap(loadFilterChainDefinitions());
                // 重新生成过滤链
                Map<String, String> chains = shiroFilterFactoryBean.getFilterChainDefinitionMap();
                if (!CollectionUtils.isEmpty(chains)) {
                    chains.forEach((uri, chainDefinition) -> {
                        manager.createChain(uri, chainDefinition);
                    });
                }
                log.info("重新加载shiro权限成功！");
            } catch (Exception e) {
                throw new RuntimeException("重新加载shiro拦截器失败！");
            }
        }
    }
}
